﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

using agvcontroller.Common;
using agvcsimulator.Module;
using agvcontroller.Log;
using agvcontroller.Common.DataBase;

namespace agvcsimulator.GUI
{
    /// <summary>
    /// Interaction logic for UCVehicleSim.xaml
    /// </summary>
    public partial class UCVehicleSim : UserControl
    {
        CVehicleSim VehicleSim;

        Timer tmrMoving;

        Logger Log;
        CAGVCDB AGVCDB;

        bool InitilizeCompleted = false;

        public UCVehicleSim()
        {
            InitializeComponent();
        }

        public UCVehicleSim(object vehicle)
        {
            InitializeComponent();

            AGVCDB = CAGVCDB.getInstance();
            VehicleSim = (CVehicleSim)vehicle;
            
            InitParameter();
            InitUI();
            RegisterEvent();

            InitilizeCompleted = true;
        }

        int GetDataFromDB()
        {

            return CReturnCode.SUCCESS;
        }

        public void tmrMoving_Elapsed(object state)
        {
        }

        private void Grid_Loaded(object sender, RoutedEventArgs e)
        {
        }

        void InitParameter()
        {
            Log = new Logger(string.Format("UCVehicleSim[{0}]",VehicleSim.Name));;

            tmrMoving = new Timer(new TimerCallback(this.tmrMoving_Elapsed), null, 0, VehicleSim.MovingInterval);

            Log.Info("InitParameter");
        }

        void RegisterEvent()
        {
            VehicleSim.onReportConnection += new deleReportConnectionSim(VehicleSim_onReportConnection);

            Logger.onDisplayLog += new deleLogDisplay(Logger_onDisplayLog);
        }

        void Logger_onDisplayLog(object sender, string msg, enumLogLevel level)
        {
            if (((Logger)sender).LogName ==VehicleSim.SimDriver.Name || ((Logger)sender).LogName == VehicleSim.Name)
            {
                DisplayLog(msg);
            }
        }

        void DisplayLog(string msg)
        {
            System.Windows.Threading.DispatcherOperation
          dispatcherOp = tbLog.Dispatcher.BeginInvoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
                tbLog.AppendText(string.Format("{0}\r\n",msg));
                tbLog.ScrollToEnd();
            }
            ));
        }

        void VehicleSim_onReportConnection(object sender, enumConnect connect)
        {
            DisplayConnection(connect);
        }

        void DisplayConnection(enumConnect connect)
        {
            System.Windows.Threading.DispatcherOperation
          dispatcherOp = lbConnect.Dispatcher.BeginInvoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
                lbConnect.Content = enumConnectString.ConvertString(connect);
            }
            ));

        }       

        void DisplayMsg(string msg)
        {
            System.Windows.Threading.DispatcherOperation
          dispatcherOp = tbLog.Dispatcher.BeginInvoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
                tbLog.Text +=string.Format("[{0}] {1} \r\n",DateTime.Now.ToShortTimeString(), msg);
            }
            ));
        }

        void InitUI()
        {
            lbVehicleSimName.Content = VehicleSim.Name;
            lbConnect.Content = "Disconnect";
        }

        void UpdateVehicleInfo()
        {
            tbPreNode.Text = VehicleSim.PreNode.ToString();
            tbCurNode.Text = VehicleSim.CurNode.ToString();
            tbNextNode.Text = VehicleSim.NextNode.ToString();

            cbConnect.SelectedIndex = (int)VehicleSim.Connect;
            cbControl.SelectedIndex = (int)VehicleSim.ControlState;
            cbCommunication.SelectedIndex = (int)VehicleSim.Commnuication;
            cbOperation.SelectedIndex = (int)VehicleSim.Operation;

            if(VehicleSim.CurVehicleJob !=null)
            {
                tbVehicleJobID.Text = VehicleSim.CurVehicleJob == null ? "none" : VehicleSim.CurVehicleJob.ID;
                //tbSource.Text = VehicleSim.CurVehicleJob == null ? "none" : VehicleSim.CurVehicleJob.Sou;

                lvRoute.Items.Clear();
                foreach (CNode node in VehicleSim.CurVehicleJob.Route)
                {
                    lvRoute.Items.Add(node.ID);
                }

                lvSpeed.Items.Clear();
                foreach (int speed in VehicleSim.CurVehicleJob.Speed)
                {
                    lvSpeed.Items.Add(speed);
                }

                lvDirect.Items.Clear();
                foreach (enumVehicleDirect direct in VehicleSim.CurVehicleJob.Direct)
                {
                    lvDirect.Items.Add(enumVehicleDirectString.ConvertString(direct));
                }

                lvAction.Items.Clear();
                foreach (enumAction action in VehicleSim.CurVehicleJob.Action)
                {
                    lvAction.Items.Add(enumActionString.ConvertString(action));
                }
            }

            tbMovingInterval.Text = VehicleSim.MovingInterval.ToString();

            Log.Info("UpdateVehicleInfo");
        }

        private void btnSet_Click(object sender, RoutedEventArgs e)
        {
            VehicleSim.ReportAlarm(Convert.ToInt32(cbAlarmID.SelectedValue), true);
        }

        private void btnRelease_Click(object sender, RoutedEventArgs e)
        {
            VehicleSim.ReportAlarm(Convert.ToInt32(cbAlarmID.SelectedValue), false);
        }

        private void cbConnect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!InitilizeCompleted) return;

            if (MessageBoxResult.Yes == MessageBox.Show(string.Format("Do you want to change {0}?", enumConnectString.ConvertString((enumConnect)cbConnect.SelectedIndex)), "Connect", MessageBoxButton.YesNo, MessageBoxImage.Question))
            {
                switch ((enumConnect)cbConnect.SelectedIndex)
                {
                    case enumConnect.CONNECTION:
                        VehicleSim.ConnectAGVC();
                        break;
                    case enumConnect.DISCONNECTION:
                        VehicleSim.DisconnectAGVC();
                        break;
                }
            }
        }

        private void cbCommunication_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!InitilizeCompleted) return;

            if (MessageBoxResult.Yes == MessageBox.Show(string.Format("Do you want to change {0}?", enumCommnicationString.ConvertString((enumCommnication)cbCommunication.SelectedIndex)), "Connect", MessageBoxButton.YesNo, MessageBoxImage.Question))
            {
                switch ((enumCommnication)cbCommunication.SelectedIndex)
                {
                    case enumCommnication.ONLINE:
                        VehicleSim.ReportCommnication(enumCommnication.ONLINE);
                        break;
                    case enumCommnication.OFFLINE:
                        VehicleSim.ReportCommnication(enumCommnication.OFFLINE);
                        break;
                }
            }
        }

        private void cbOperation_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!InitilizeCompleted) return;

            if (MessageBoxResult.Yes == MessageBox.Show(string.Format("Do you want to change {0}?", enumOperationString.ConvertString((enumOperation)cbOperation.SelectedIndex)), "Connect", MessageBoxButton.YesNo, MessageBoxImage.Question))
            {
                switch ((enumOperation)cbOperation.SelectedIndex)
                {
                    case enumOperation.AUTO:
                        VehicleSim.ReportOperation(enumOperation.AUTO);
                        break;
                    case enumOperation.MANUAL:
                        VehicleSim.ReportOperation(enumOperation.MANUAL);
                        break;
                }
            }
        }

        private void cbControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (InitilizeCompleted==false) return;

            if (MessageBoxResult.Yes == MessageBox.Show(string.Format("Do you want to change {0}?", enumContolStateString.ConvertString((enumContolState)cbControl.SelectedIndex)), "Connect", MessageBoxButton.YesNo, MessageBoxImage.Question))
            {
                switch ((enumContolState)cbControl.SelectedIndex)
                {
                    case enumContolState.RUN:
                        VehicleSim.ReportControlState(enumContolState.RUN);
                        break;
                    case enumContolState.IDLE:
                        VehicleSim.ReportControlState(enumContolState.IDLE);
                        break;
                    case enumContolState.DOWN:
                        VehicleSim.ReportControlState(enumContolState.DOWN);
                        break;
                    case enumContolState.CHARGER:
                        VehicleSim.ReportControlState(enumContolState.CHARGER);
                        break;
                }
            }
        }

        private void btnReportPosition_Click(object sender, RoutedEventArgs e)
        {
            int preNode;
            int curNode;
            int nextNode;
            try
            {
                preNode = Convert.ToInt32(tbPreNode.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Pre Node ID is invalid");
                return;
            }

            try
            {
                curNode = Convert.ToInt32(tbCurNode.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Current Node ID is invalid");
                return;
            }

            try
            {
                nextNode = Convert.ToInt32(tbNextNode.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Next Node ID is invalid");
                return;
            }

            VehicleSim.ReportPosition(preNode, curNode, nextNode);
        }
    }
}